home
***
CD-ROM
|
disk
|
FTP
|
other
***
search
/
Amiga Plus Special 25
/
AMIGAplus Sonderheft 25 (2000)(Falke)(DE)(Track 1 of 4)[!].iso
/
Updates
/
PowerPC
/
CyberFIX
/
CSPPC233Fix_wos.c
< prev
next >
Wrap
C/C++ Source or Header
|
2000-05-16
|
3KB
|
100 lines
/*
** CSPPC233Fix_wos.c
**
** An Instruction Access Exception handler, which tries to recover from
** a hardware bug on CSPPC/233 cards by fixing the trashed LR register.
**
** Written by Frank Wille <frank@phoenix.owl.de>.
** This code is PUBLIC DOMAIN.
**
*/
#include <stdio.h>
#include <time.h>
#include <dos/dos.h>
#include <powerpc/powerpc.h>
#include <powerpc/tasksPPC.h>
#include <clib/powerpc_protos.h>
static int sigExcept; /* exception notification signal */
static struct EXCContext EC; /* copy of exception context */
static struct TaskPPC *thisTask; /* this task */
static struct TaskPPC *excTask; /* excepting task */
ULONG IAccessException(struct EXCContext *);
/* This line is vbcc-specific, the rest should be portable (to
Storm-C, for example). Although I doubt that gcc-WarpOS would
work, because the exception handler should be PowerOpen-ABI). */
ULONG r2(void) = "\tmr\tr3,r2"; /* gets TOC-pointer */
main()
{
static ULONG cnt=0;
struct TagItem ti[8];
void *xhdl;
ULONG sigmsk;
if ((sigExcept = AllocSignalPPC(-1)) >= 0) {
thisTask = FindTaskPPC(NULL);
/* install a global handler for Instruction Access Exceptions */
ti[0].ti_Tag = EXCATTR_CODE;
ti[0].ti_Data = (ULONG)IAccessException;
ti[1].ti_Tag = EXCATTR_DATA;
ti[1].ti_Data = r2();
ti[2].ti_Tag = EXCATTR_EXCID;
ti[2].ti_Data = EXCF_IACCESS;
ti[3].ti_Tag = EXCATTR_FLAGS;
ti[3].ti_Data = EXCF_GLOBAL | EXCF_LARGECONTEXT;
ti[4].ti_Tag = EXCATTR_PRI;
ti[4].ti_Data = 127;
ti[5].ti_Tag = EXCATTR_NAME;
ti[5].ti_Data = (ULONG)"Trashed-LR bug fix for CSPPC/233";
ti[6].ti_Tag = TAG_DONE;
if (xhdl = SetExcHandler(ti)) {
printf("Instruction Access exception handler installed.\n"
"Press CTRL-C to quit.\n");
do {
/* wait for an exception or the signal to quit (CTRL-C) */
sigmsk = WaitPPC((1L<<sigExcept) | (1L<<SIGBREAKB_CTRL_C));
if (sigmsk & (1L<<sigExcept)) {
/* print exception info */
time_t tim;
char buf[32];
time(&tim);
strftime(buf,sizeof(buf),"%x",localtime(&tim));
printf("**(%lu) %s Trashed LR: 0x%08lx Task: %08lx (%s)\n",
++cnt,buf,EC.ec_LR,(ULONG)excTask,
excTask->tp_Task.tc_Node.ln_Name);
}
}
while (!(sigmsk & (1L<<SIGBREAKB_CTRL_C)));
RemExcHandler(xhdl);
}
FreeSignalPPC(sigExcept);
}
}
ULONG IAccessException(struct EXCContext *ec)
{
/* first check if this exception was caused by a trashed LR register */
if (ec->ec_UPC.ec_SRR0 == ec->ec_LR && (ec->ec_LR & 0xf0000000) != 0) {
CopyMemPPC(ec,&EC,sizeof(struct EXCContext)); /* save exception ctxt. */
ec->ec_UPC.ec_SRR0 &= 0x0fffffff; /* fix PC and LR */
ec->ec_LR &= 0x0fffffff;
excTask = FindTaskPPC(NULL);
SignalPPC(thisTask,1L<<sigExcept); /* show exception info */
return (EXCRETURN_ABORT); /* retry instruction access */
}
return (EXCRETURN_NORMAL);
}